package cqrtplm.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.http.HttpUtil;
import co.elastic.clients.elasticsearch.security.User;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hustcad.plm.pdm.ec.module.dto.ECObjData;
import com.hustcad.plm.pdm.ec.module.vo.ECLinkObjDataCommonVO;
import com.hustcad.plm.pdm.ec.service.TyplmEcAgainstDataService;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowChangeRequestView;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowObject;
import com.hustcad.plm.pdm.flowbusiness.model.entity.WorkFlowObjectPackage;
import com.hustcad.plm.pdm.workflow.model.entity.WorkFlowContainerView;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowChgFormView;
import com.hustcad.plm.pdm.form.model.dto.FormDataDTO;
import com.hustcad.plm.pdm.form.model.vo.TyplmFormDataVO;
import com.hustcad.plm.pdm.form.service.TyFormDataExtService;
import com.hustcad.plm.pdm.formusage.service.TyplmFormDataValueService;
import com.hustcad.plm.pdm.workflow.service.TyplmWorkFlowContainerService;
import com.lark.oapi.okhttp.OkHttpClient;
import com.lark.oapi.okhttp.Request;
import com.lark.oapi.okhttp.Response;
import com.ty.basic.entity.IdentifierEntity;
import com.ty.basic.entity.org.UserDO;
import com.ty.basic.session.TyAccountContext;
import cqrtplm.common.CommonService;
import cqrtplm.dto.OAProjectJobDTO;
import cqrtplm.entity.WorkflowMapping;
import cqrtplm.mapper.OaApiMapper;
import cqrtplm.service.OaApiService;
import cqrtplm.vo.TyJobVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class OaApiServiceImpl implements OaApiService {

    private static final Logger log = LoggerFactory.getLogger(OaApiServiceImpl.class);
    @Resource
    private RTOaIntegrityServiceImpl rtOaIntegrityService;
    @Resource
    private TyplmWorkFlowContainerService typlmWorkFlowContainerService;
    @Resource
    private TyplmEcAgainstDataService typlmEcAgainstDataService;

    @Resource
    private OaApiMapper oaApiMapper;

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private CommonService commonService;

    @Resource
    private TyFormDataExtService tyFormDataExtService;

    @Resource
    private TyplmFormDataValueService typlmFormDataValueService;
    @Resource
    WorkflowMappingServiceImpl workflowMappingService;

    @Value("${rato.process_check_url}")
    private String processCheckUrl;

    @Override
    public String getProjectIdByName(String field0003) {
        return oaApiMapper.getProjectIdByName(field0003);
    }

    @Override
    public List<TyJobVO> obtainTheProjectTaskId(String pjOid) {
        return oaApiMapper.obtainTheProjectTaskId(pjOid);
    }

    @Override
    public void updateProjectJobTime(OAProjectJobDTO p) {
        oaApiMapper.updateProjectJobTime(p);
    }

    @Override
    public String selectProjectIdByName(String name) {
        return oaApiMapper.selectProjectIdByName(name);
    }

    @Override
    public String updatePlanActivity(JSONArray jsonArray) {
        org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
        headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        headers.set(org.springframework.http.HttpHeaders.AUTHORIZATION, TyAccountContext.getToken());
        HttpEntity<String> requestEntity = new HttpEntity<>(jsonArray.toJSONString(), headers);
        ResponseEntity<String> exchange = restTemplate.exchange("http://127.0.0.1:9588/api/v1/oaApi/updatePlanDate",
                                                                HttpMethod.POST,
                                                                requestEntity,
                                                                String.class);
        return exchange.getBody();

    }

    /**
     * 发送零星采购表单数据到OA
     *
     * @param workFlowContainerId 流程实例ID
     */
    @Override
    public void sendFormDataToOa(BigInteger workFlowContainerId) {
        List<IdentifierEntity> flowObjEntityList = commonService.getFlowObjListByWorkFlowContainer(workFlowContainerId);
        for (IdentifierEntity entity : flowObjEntityList) {
            TyplmFormDataVO formDataVO = this.tyFormDataExtService.getFormDataDetail(entity.getOid());
            JSONObject formdata = formDataVO.getFormdata();
            JSONArray moldOpeningList = formdata.getJSONArray("MoldOpeningList");
            JSONObject testObj = formdata.getJSONObject("testObj");
            JSONObject fromData = new JSONObject();
            JSONObject tableHead = new JSONObject();
            tableHead.put("field0001", testObj.containsKey("flowCode") ? "" : testObj.getString("flowCode")); // 流程编号
            tableHead.put("field0004", TyAccountContext.getUser().getName());
            tableHead.put("field0013", testObj.containsKey("@Cost") ? "" : testObj.getString("@Cost")); // 成本中心
            tableHead.put("field0058", testObj.containsKey("@Type") ? "" : testObj.getString("@Type")); // 类型
            tableHead.put("field0007",
                          testObj.containsKey("@Illustrate") ? "" : testObj.getString("@Illustrate")); //申请说明
            tableHead.put("field0059", testObj.containsKey("@NewItem") ? "" : testObj.getString("@NewItem")); // 是否新物料
            tableHead.put("field0068", testObj.containsKey("@SAPProjectNumber") ? "" : testObj.getString(
                    "@SAPProjectNumber")); // SAP项目令号
            tableHead.put("field0071", testObj.containsKey("@Place") ? "" : testObj.getString("@Place")); // 采购地
            tableHead.put("field0074", testObj.containsKey("@Shipping") ? "" : testObj.getString("@Shipping")); // 发运方式
            tableHead.put("formDataId", entity.getOid());
            JSONArray tableLine = new JSONArray();
            for (int i = 0; i < moldOpeningList.size(); i++) {
                JSONObject formDataLine = moldOpeningList.getJSONObject(i);
                JSONObject tableLineData = new JSONObject();
                tableLineData.put("field0008", formDataLine.containsKey("DrawingCode2") ? "" : formDataLine.getString(
                        "DrawingCode2")); // 物料编码
                tableLineData.put("field0017",
                                  formDataLine.containsKey("ItemDescription") ? "" : formDataLine.getString(
                                          "ItemDescription")); //物料描述
                tableLineData.put("field0019", formDataLine.containsKey("UnitMeasure") ? "" : formDataLine.getString(
                        "UnitMeasure")); // 计量单位
                tableLineData.put("field0073", formDataLine.containsKey("Material") ? "" : formDataLine.getString(
                        "Material")); // 零件材质
                tableLineData.put("field0018",
                                  formDataLine.containsKey("QuantityRequired") ? "" : formDataLine.getString(
                                          "QuantityRequired")); //需求数量
                tableLineData.put("field0055", formDataLine.containsKey("ExpectArrive") ? "" : formDataLine.getDate(
                        "ExpectArrive")); //期望到货日期
                tableLineData.put("field0052", formDataLine.containsKey("RequestDate") ? "" : formDataLine.getDate(
                        "RequestDate")); //需求日期
                tableLineData.put("field0025",
                                  formDataLine.containsKey("Factory") ? "" : formDataLine.getString("Factory")); // 工厂
                tableLineData.put("field0056", formDataLine.containsKey("PurchaseGroup") ? "" : formDataLine.getString(
                        "PurchaseGroup")); //采购组
                tableLine.add(tableLineData);
            }
            fromData.put("formmain_13584", tableHead);
            fromData.put("formson_13585", tableLine);
            JSONObject json = new JSONObject();
            JSONObject data1 = new JSONObject();
            data1.put("data", fromData);
            data1.put("subject", "");
            data1.put("draft", "0");
            data1.put("relateDoc", "");
            data1.put("templateCode", "reserve");
            json.put("data", data1);
            json.put("appName", "collaboration");
            log.info("发送零星采购表单数据到OA:{}", json);

        }
    }

    @Override
    public JSONObject writeBackOAFormData(JSONObject params) {
        TyplmFormDataVO formDataVO = this.tyFormDataExtService.getFormDataDetail(params.getBigInteger("formDataId"));
        JSONObject formdata = formDataVO.getFormdata();
        JSONObject testObj = formdata.getJSONObject("testObj");
        testObj.put("@PR", params.getString("pr"));
        FormDataDTO formDataDTO = new FormDataDTO();
        formDataDTO.setFormDataStr(formdata.toJSONString());
        formDataDTO.setOid(formDataVO.getOid());
        formDataDTO.setOtype(formDataVO.getOtype());
        this.typlmFormDataValueService.dealFormContentData(
                new IdentifierEntity(formDataDTO.getOid(), formDataDTO.getOtype()), null);
        this.typlmFormDataValueService.updateFormDataValue(formDataDTO);
        //自动通过中间节点
        String flowContainerId = params.getString("flowContainerId");
        return null;
    }

    /**
     * 下发订单数据
     *
     * @param workFlowContainerId
     */
    @Override
    @Transactional
    public void sendOrderDataToOa(BigInteger workFlowContainerId) {
        List<IdentifierEntity> flowObjList =
                getFlowObjListByWorkFlowContainer(
                        workFlowContainerId);
        if (CollUtil.isEmpty(flowObjList)) {
            return;
        }
        flowObjList.stream().forEach(entity -> {
            UserDO user = TyAccountContext.getUser();
            String oaToken = rtOaIntegrityService.getOAToken("22051030");
            Map<String, Object> stringObjectMap = rtOaIntegrityService.buildRequestBody(entity.getOid(), true);
            if (stringObjectMap != null) {
                rtOaIntegrityService.startProcess(oaToken, stringObjectMap, workFlowContainerId, true);
            }
        });

    }

    @Override
    public List<IdentifierEntity> getFlowObjListByWorkFlowContainer(BigInteger workFlowContainerId) {
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService
                .getWorkFlowContainerDetailByPrimaryKey(
                        workFlowContainerId);
        if (Objects.isNull(workFlowContainerView)) {
            log.info("未找到 {} 对应的流程容器", workFlowContainerId);
            return new ArrayList<>();
        }
        return getFlowObjListByWorkFlowContainer(workFlowContainerView);
    }

    @Override
    public List<IdentifierEntity> getFlowObjListByWorkFlowContainer(WorkFlowContainerView workFlowContainerView) {
        List<IdentifierEntity> flowList = new ArrayList<>();
        if ((workFlowContainerView instanceof WorkFlowObjectPackage)) {
            log.info("当前流程属于普通流程");
            WorkFlowObjectPackage workFlowObjectPackage = (WorkFlowObjectPackage) workFlowContainerView;
            List<FlowObject> flowObjectList = workFlowObjectPackage.getFlowObjectList();
            if (CollUtil.isNotEmpty(flowObjectList)) {
                flowList = flowObjectList.stream().map(
                        m -> new IdentifierEntity(m.getRefObjectOid(), m.getRefObjectOtype())).distinct().collect(
                        Collectors.toList());
            }
        } else if (workFlowContainerView instanceof FlowChgFormView) {
            log.info("当前流程属于变更流程/发布流程");
            FlowChgFormView flowChgFormView = (FlowChgFormView) workFlowContainerView;
            //            List<ECObjData> flowObjectList = flowChgFormView.getChgFormVO().getEcAffectVOS();
            List<ECObjData> flowObjectList = flowChgFormView.getChgFormVO().getEcObjDataVOS();
            if (CollUtil.isNotEmpty(flowObjectList)) {
                flowList = flowObjectList.stream().map(m -> new IdentifierEntity(m.getOid(), m.getOtype())).distinct()
                        .collect(Collectors.toList());
            }
        } else if (workFlowContainerView instanceof FlowChangeRequestView) {
            log.info("当前流程属于变更请求流程");
            List<ECLinkObjDataCommonVO> ecLinkObjDataCommonVOS = typlmEcAgainstDataService
                    .batchGetAffectedObjectListByOids(
                            Collections.singletonList(workFlowContainerView.getBaseObjectOid()),
                            workFlowContainerView.getBaseObjectOtype());
            if (CollUtil.isNotEmpty(ecLinkObjDataCommonVOS)) {
                flowList = ecLinkObjDataCommonVOS.stream().map(m -> new IdentifierEntity(m.getOid(), m.getOtype()))
                        .distinct().collect(Collectors.toList());
            }
        }
        return flowList;
    }

    /**
     * 下发改后物料信息
     *
     * @param workFlowContainerId
     */
    @Override
    public void sendOrderChangePartDataToOa(BigInteger workFlowContainerId) {
        List<IdentifierEntity> flowObjList =
                getFlowObjListByWorkFlowContainer(
                        workFlowContainerId);
        if (CollUtil.isEmpty(flowObjList)) {
            return;
        }
        flowObjList.stream().forEach(entity -> {
            UserDO user = TyAccountContext.getUser();
            String oaToken = rtOaIntegrityService.getOAToken("22051030");
            Map<String, Object> stringObjectMap = rtOaIntegrityService.buildRequestBody(entity.getOid(), false);
            if (stringObjectMap != null) {
                rtOaIntegrityService.startProcess(oaToken, stringObjectMap, workFlowContainerId, false);
            }
        });

    }

    @Override
    public Boolean checkOAFlowState(BigInteger workFlowContainerId) {
        Optional<WorkflowMapping> byId = workflowMappingService.getById(workFlowContainerId.toString());
        Boolean flag = true;
        if (byId.isPresent()) {
            WorkflowMapping workflowMapping = byId.get();
            String oaProcessOid = workflowMapping.getOaProcessOid();
            //            UserDO user = TyAccountContext.getUser();
            String oaToken = rtOaIntegrityService.getOAToken("22051030");
            Integer oaProcessState = getOaProcessState(oaProcessOid, oaToken);
            if (oaProcessState == 0) {
                flag = true;
            } else {
                flag = false;
            }
        }
        return flag;
    }

    /**
     * 查询流程状态
     */

    public Integer getOaProcessState(String oaProcessOid, String token) {

        String fullUrl = processCheckUrl.replace("{flowId}", oaProcessOid) + "?token=" + token;
        try {
            String response = HttpUtil.get(fullUrl);
            Integer folwStatus = JSONObject.parseObject(response, Integer.class);
            return folwStatus;
        } catch (Exception e) {
            throw new RuntimeException("查询流程状态失败: " + e.getMessage());
        }

    }
}

